widget: Change slightly the gesture cancellation policy in a same widget
authorCarlos Garnacho <carlosg@gnome.org>
Tue, 6 May 2014 12:12:13 +0000 (14:12 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Fri, 23 May 2014 17:54:29 +0000 (19:54 +0200)
Within a widget, if a gesture accepts a sequence, it would previously
cancel every other gesture that not in the same group. Change this to
only cancelling gestures that previously claimed the gesture, and let
gestures with state=NONE for that sequence remain like that.

This enables late recognition of gestures, even on the presence of
another gesture group that was more eager at claiming the gesture.

One usecase is user-defined panning gestures on scrolledwindows,
if ::capture-button-press is TRUE (eg. the default), the gesture is
claimed early in order to consume the button press, but that would
tipically make every other gesture group deny the sequence. With
this change, the pan gesture can keep state=NONE, and later claim
the sequence for itself if the panning gesture is recognized.

Also, do not propagate state=DENIED to every gesture in the widget,
that was unintended.

gtk/gtkwidget.c

index d201bc824a62c62c7efd49a8adb1128d86db4442..8e8d66325d5d2102239530e7b9812cbdf9c95851 100644 (file)
@@ -4220,18 +4220,23 @@ _gtk_widget_set_sequence_state_internal (GtkWidget             *widget,
           !gtk_gesture_handles_sequence (gesture, seq))
         seq = NULL;
 
-      /* If a group is provided, ensure only gestures pertaining to the group
-       * get a "claimed" state, all other gestures must deny the sequence.
-       */
-      if (group && gesture_state == GTK_EVENT_SEQUENCE_CLAIMED &&
-          !g_list_find (group, data->controller))
-        gesture_state = GTK_EVENT_SEQUENCE_DENIED;
+      if (group && !g_list_find (group, data->controller))
+        {
+          /* If a group is provided, ensure only gestures pertaining to the group
+           * get a "claimed" state, all other claiming gestures must deny the sequence.
+           */
+          if (gesture_state == GTK_EVENT_SEQUENCE_CLAIMED &&
+              gtk_gesture_get_sequence_state (gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
+            gesture_state = GTK_EVENT_SEQUENCE_DENIED;
+          else
+            continue;
+        }
 
       g_signal_handler_block (data->controller, data->sequence_state_changed_id);
 
       sequence_handled =
         _gtk_gesture_handled_sequence_press (gesture, seq);
-      retval = gtk_gesture_set_sequence_state (gesture, seq, state);
+      retval = gtk_gesture_set_sequence_state (gesture, seq, gesture_state);
       handled |= retval;
 
       g_signal_handler_unblock (data->controller, data->sequence_state_changed_id);